<template>
  <div class="crud-checkbox" :class="computedClasses">
    <el-checkbox v-model="localChecked" :indeterminate="indeterminate" :disabled="disabled" :size="size"
      :true-label="trueValue" :false-label="falseValue" class="crud-checkbox__inner" v-bind="$attrs" @change="onChange">
      <slot>{{ label }}</slot>
    </el-checkbox>
    <span v-if="description" class="crud-checkbox__desc">{{ description }}</span>
  </div>
  <div v-if="hint" class="crud-checkbox__hint">{{ hint }}</div>
  <div v-if="error" class="crud-checkbox__error">{{ error }}</div>
  <div v-if="help" class="crud-checkbox__help">{{ help }}</div>
  <div v-if="border" class="crud-checkbox__border" />
</template>

<script setup lang="ts">
import { computed, ref, toRefs, watch } from 'vue'

type CheckboxSize = 'large' | 'default' | 'small'

interface Props {
  modelValue?: boolean | string | number
  indeterminate?: boolean
  disabled?: boolean
  size?: CheckboxSize
  trueValue?: string | number
  falseValue?: string | number
  label?: string
  description?: string
  hint?: string
  error?: string
  help?: string
  border?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  indeterminate: false,
  disabled: false,
  size: 'default',
  border: false
})

defineOptions({ inheritAttrs: false })

const emit = defineEmits<{
  (e: 'update:modelValue', v: boolean | string | number): void
  (e: 'change', v: boolean | string | number): void
}>()

const { modelValue, indeterminate, disabled, size } = toRefs(props)

type Model = boolean | string | number
const localChecked = ref<Model>(modelValue.value as Model)

watch(
  () => modelValue.value,
  (v: Model) => {
    localChecked.value = v as Model
  }
)

const onChange = (val: Model) => {
  emit('update:modelValue', val)
  emit('change', val)
}

const computedClasses = computed(() => ({
  'is-disabled': disabled.value,
  'is-indeterminate': props.indeterminate,
  [`size-${size.value}`]: true
}))
</script>

<style scoped>
.crud-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  transition: background-color 0.2s ease, box-shadow 0.2s ease;
}

.crud-checkbox:hover {
  background-color: var(--el-fill-color-light);
}

.crud-checkbox.is-disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.crud-checkbox__desc {
  color: var(--el-text-color-regular);
  font-size: 12px;
}

.crud-checkbox__hint {
  margin-top: 4px;
  color: var(--el-color-info);
  font-size: 12px;
}

.crud-checkbox__error {
  margin-top: 4px;
  color: var(--el-color-error);
  font-size: 12px;
}

.crud-checkbox__help {
  margin-top: 4px;
  color: var(--el-text-color-secondary);
  font-size: 12px;
}

.crud-checkbox__border {
  height: 1px;
  background: var(--el-border-color-light);
  margin-top: 8px;
}

.size-large {
  font-size: 14px;
}

.size-default {
  font-size: 13px;
}

.size-small {
  font-size: 12px;
}
</style>

<style scoped lang="scss">
/* 自定义复选框选中颜色为主题色 */
.crud-checkbox__inner :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
  background-color: var(--primary-color, $primary-color);
  border-color: var(--primary-color, $primary-color);
}

.crud-checkbox__inner :deep(.el-checkbox__input.is-indeterminate .el-checkbox__inner) {
  background-color: var(--primary-color, $primary-color);
  border-color: var(--primary-color, $primary-color);
}

.crud-checkbox__inner :deep(.el-checkbox__input.is-checked .el-checkbox__inner::after) {
  border-color: #fff;
}

.crud-checkbox__inner :deep(.el-checkbox__input.is-focus .el-checkbox__inner) {
  border-color: var(--primary-color, $primary-color);
}

.crud-checkbox__inner :deep(.el-checkbox__input:hover .el-checkbox__inner) {
  border-color: var(--primary-color-hover, $primary-color-hover);
}

/* 选中状态文字颜色改为主题色 */
.crud-checkbox__inner :deep(.el-checkbox.is-checked .el-checkbox__label) {
  color: var(--primary-color, $primary-color);
  font-weight: 500;
}

/* 半选状态文字颜色改为主题色 */
.crud-checkbox__inner :deep(.el-checkbox.is-indeterminate .el-checkbox__label) {
  color: var(--primary-color, $primary-color);
  font-weight: 500;
}

.crud-checkbox__inner :deep(.el-checkbox:hover .el-checkbox__label) {
  color: var(--primary-color-hover, $primary-color-hover);
}

/* 默认状态文字颜色 */
.crud-checkbox__inner :deep(.el-checkbox__label) {
  color: $text-color-primary;
  transition: color 0.2s ease;
}

// 深色模式适配
@media (prefers-color-scheme: dark) {
  .crud-checkbox {
    &:hover {
      background-color: $hover-bg-light-dark;
    }

    .crud-checkbox__desc {
      color: $text-color-secondary-dark;
    }

    .crud-checkbox__hint {
      color: $info-color-hover;
    }

    .crud-checkbox__error {
      color: $danger-color-hover;
    }

    .crud-checkbox__help {
      color: $text-color-muted-dark;
    }

    .crud-checkbox__border {
      background: $border-color-light-dark;
    }
  }

  .crud-checkbox__inner :deep(.el-checkbox__label) {
    color: $text-color-primary-dark;
  }

  .crud-checkbox__inner :deep(.el-checkbox.is-checked .el-checkbox__label) {
    color: var(--primary-color-light, $primary-color-light);
  }

  .crud-checkbox__inner :deep(.el-checkbox.is-indeterminate .el-checkbox__label) {
    color: var(--primary-color-light, $primary-color-light);
  }

  .crud-checkbox__inner :deep(.el-checkbox:hover .el-checkbox__label) {
    color: var(--primary-color-light, $primary-color-light);
  }

  .crud-checkbox__inner :deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
    background-color: var(--primary-color, $primary-color);
    border-color: var(--primary-color, $primary-color);
  }

  .crud-checkbox__inner :deep(.el-checkbox__input.is-indeterminate .el-checkbox__inner) {
    background-color: var(--primary-color, $primary-color);
    border-color: var(--primary-color, $primary-color);
  }

  .crud-checkbox__inner :deep(.el-checkbox__input:hover .el-checkbox__inner) {
    border-color: var(--primary-color-light, $primary-color-light);
  }
}
</style>
